﻿#pragma once

#include "Texture/Texture2D.h"
#include "Font/Font.h"
#include "Framework/ApplicationSubsystem.h"

#include "Math/Math.h"

#include "FontSubsystem.m.h"

class RTextTexturePool;

RCLASS()
class WHENGINE_API RFontApplicationSubsystem: public RApplicationSubsystem
{
    ROBJECT

    virtual void Initialize() override;
    virtual void Deinitialize() override;

public:

    static RFontApplicationSubsystem* Get();

    RFUNCTION()
    static RFontApplicationSubsystemPtr GetInstance();

    RFUNCTION()
    TSharedObjectPtr<RFont> LoadFontFromFile(const SPath& FontFile);

    TSharedObjectPtr<RFont> LoadFontFromBinary(const TVector<uint8_t>& InFontBinary);

    // how size of area that text need on screen
    SIntPoint GetOccupiedSize(const CString& Text,TSharedObjectPtr<RFont> InFont,uint32_t FontSize);
    
    // width of area that text need on screen, include space
    // donot support multi-line text
    float GetSingleLineOccupiedWidth(const CString& SingleLineText,TSharedObjectPtr<RFont> InFont,uint32_t FontSize);

    //return index of character that cursor should placed before it
    int64_t CalculateCursorIndex(const CString& LineText,TSharedObjectPtr<RFont> InFont,uint32_t FontSize,float MouseX); 

    //return cursor position in pixel
    struct SCursorPosition
    {
        SCursorPosition()=default;

        SCursorPosition(int64_t InCharacterIndex,float InX):CharacterIndex(InCharacterIndex),X(InX){}

        int64_t CharacterIndex=0; //index of character that cursor should placed before it
        float X=0; //cursor position in pixel
    };

    SCursorPosition CalculateCursorPosition(const CString& LineText,TSharedObjectPtr<RFont> InFont,uint32_t FontSize,float MouseX); 


    RFUNCTION()
    void SetDefaultFont(TSharedObjectPtr<RFont> InFont)
    {
        DefaultFont=InFont;
    }

    RFUNCTION()
    TSharedObjectPtr<RFont> GetDefaultFont();


    RFUNCTION()
    void SetFallBackFont(TSharedObjectPtr<RFont> InFont)
    {
        FallBackFont=InFont;
    }

    RFUNCTION()
    TSharedObjectPtr<RFont> GetFallBackFont()
    {
        return FallBackFont;
    }

    TSharedObjectPtr<RTextTexturePool> GetTextTexturePool()
    {
        return TextTexturePool;
    }
private:
    //default font engine widget to use 
    TSharedObjectPtr<RFont> DefaultFont;
    //fallback font to use when default font can't render some character
    TSharedObjectPtr<RFont> FallBackFont;

    // type is FT_Library
    void* LowLevelFreeTypeLibrary=nullptr;

    //字符纹理池
    TSharedObjectPtr<RTextTexturePool> TextTexturePool;
    

};